using System;

namespace SharpMud.Text.Escaping
{
	/// <summary>
	/// Provides functionality for escaping text/data using C# string escaping notation
	/// </summary>
	public class CSharp
	{
		private CSharp()
		{
		}

		protected static string[,] BasicEscapesChart = new string[,] {
			//	Normal Value
			//     |   Escaped Value
			//     |     |
			//     |     |
			{"\n",@"\n"},		// Newline
			{"\r",@"\r"},		// Carriage Return
			{"\t",@"\t"},		// Horizontal Tab
			{"\v",@"\v"},		// Vertical Tab
			{"\'",@"\'"},		// Single Quote
			{"\a",@"\a"},		// Alert
			{"\b",@"\b"},		// Backspace
			{"\f",@"\f"},		// Form Feed
			{"\0",@"\0"},		// NULL
			{"\x01",@"\x01"},
			{"\x02",@"\x02"},
			{"\x03",@"\x03"},
			{"\x04",@"\x04"},
			{"\x05",@"\x05"},
			{"\x06",@"\x06"},
			{"\x0E",@"\x0E"},
			{"\x0F",@"\x0F"},
			{"\x10",@"\x10"},
			{"\x11",@"\x11"},
			{"\x12",@"\x12"},
			{"\x13",@"\x13"},
			{"\x14",@"\x14"},
			{"\x15",@"\x15"},
			{"\x16",@"\x16"},
			{"\x17",@"\x17"},
			{"\x18",@"\x18"},
			{"\x19",@"\x19"},
			{"\x1A",@"\x1A"},
			{"\x1B",@"\x1B"},
			{"\x1C",@"\x1C"},
			{"\x1D",@"\x1D"},
			{"\x1E",@"\x1E"},
			{"\x1F",@"\x1F"},
			//{"\x20",@"\x20"}, // Space
			{"\x7F",@"\x7F"},	// Escape
			{"\\",@"\\"},		// Backslash
			{"\"",@"\"""}		// Double Quote
		};
		
		protected static bool IsEscapedCharacter(string val, int index)
		{
			if(val[index]!='\\')
				return false;
			for(int x=0;x<BasicEscapesChart.GetLength(0);x++)
			{
				if(val.Substring(index,((string)BasicEscapesChart.GetValue(x,1)).Length)
					==
					((string)BasicEscapesChart.GetValue(x,1))
					)
				{
					return true;
				}
			}
            /*
			index++;
			if(val[index]=="x")
			{
				return true;
			}
			if(val[index]=="u")
			{
				return true;
			}
			*/
			return false;
		}

		protected static char UnescapeCharacter(string val, ref int index)
		{
			if(val[index]!='\\')
			{
				index++;
				return val[index-1];
			}
			for(int x=0;x<BasicEscapesChart.GetLength(0);x++)
			{
				if(String.Compare(val.Substring(index,((string)BasicEscapesChart.GetValue(x,1)).Length),((string)BasicEscapesChart.GetValue(x,1)),true)==0)
				{
					index = (index + ((string)BasicEscapesChart.GetValue(x,1)).Length)-1;
					return (((string)BasicEscapesChart.GetValue(x,0)))[0];
				}
			}
			/*
			index++;
			if(val[index]=="x")
			{
				return true;
			}
			if(val[index]=="u")
			{
				return true;
			}
			*/
			throw new FormatException();
		}

		protected static string EscapeCharacter(char c)
		{
			for(int x=0;x<BasicEscapesChart.GetLength(0);x++)
			{
				if(c==(((string)BasicEscapesChart.GetValue(x,0)))[0])
				{
					return ((string)BasicEscapesChart.GetValue(x,1));
				}
			}
			return c.ToString();
		}

		public static string Escape(string text)
		{
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			foreach(char c in text.ToCharArray())
			{
				sb.Append(EscapeCharacter(c));
			}
			return sb.ToString();
		}

		public static string Unescape(string text)
		{
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			int x = 0;
			for(x=0;x<text.Length;x++)
			{
				if(IsEscapedCharacter(text,x))
				{
					sb.Append(UnescapeCharacter(text,ref x));
				}
				else
				{
					sb.Append(text[x]);
				}
			}
			return sb.ToString();
		}
	}
}
